#ifndef MBREGHANDLER_H
#define MBREGHANDLER_H
//#include "check_type.h"
#include <QObject>
#include <QMutex>
#include <stdint.h>
#include "mb.h"
#include "myserialport/spscaleadaptor.h"
#define MB_FLOAT	2
#define MB_INT		1
#define MB_LONG 	2
class MainWidget;
class MBRegHandler;
typedef struct {
	uint16_t reg_no;
	uint8_t size;
	void (MBRegHandler::*fun_read)(uint8_t *);
} INPUT_REG;

typedef struct {
	uint16_t reg_no;
	uint8_t	size;
	void (MBRegHandler::*fun_read)(uint8_t *);
	void (MBRegHandler::*fun_write)(const uint8_t *);
} HOLDING_REG;


typedef struct {
	uint16_t reg_no;
	uint8_t (MBRegHandler::*fun_read)(void);
	void (MBRegHandler::*fun_write)(uint8_t);
} SINGLE_COIL;

typedef struct {
	uint16_t reg_no;
	uint8_t (MBRegHandler::*fun_read)(void);
} DISCRETE_INPUT;

enum EndianMode{
    ENDIAN_MODE_SMALL,
    ENDIAN_MODE_BIG
};

class MBRegHandler :public QObject
{
    Q_OBJECT
public:
    static MBRegHandler *getHandler(MainWidget *parent=NULL){
        if(mHandler==NULL){
            mHandler = new MBRegHandler(parent);
        }
        return mHandler;
    }
    enum ChkRslt
    {
        CHECK_NONE = 0,
        CHECK_LOW,
        CHECK_OK,
        CHECK_HI,
        CHECK_END
    };

    eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs );
    eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete );
    eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode );
    eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode );

    void updateCheckRslt(ChkRslt s){
        mChkRslt = s;
    }
private:

    void MB_getFloatNet(uint8_t *reg);
    void MB_getFloatTare(uint8_t *reg);
    void MB_getFloatGross(uint8_t *reg);
    void MB_getFloatFull(uint8_t *reg);

    void MB_getDeci(uint8_t *reg);
    void MB_setDeci(const uint8_t *reg);
    void MB_getDiv(uint8_t *reg);
    void MB_getUnit(uint8_t *reg);


    void MB_getLongNet(uint8_t *reg);
    void MB_getLongTare(uint8_t *reg);
    void MB_getLongGross(uint8_t *reg);


    void MB_setDiv(const uint8_t *reg);

    void MB_setFloatFull(const uint8_t *reg);

    void MB_getLongFull(uint8_t *reg);
    void MB_getDevAddr(uint8_t *reg);
    void MB_setDevAddr(const uint8_t *reg);


    void MB_getFloatHi(uint8_t *reg);
    void MB_setFloatHi(const uint8_t *reg);


    void MB_getFloatLo(uint8_t *reg);
    void MB_setFloatLo(const uint8_t *reg);

    void MB_getScaleSatus(uint8_t *reg);

    void MB_setEndian(uint8_t reg);
    void MB_setFloatTare(const uint8_t *reg);
    uint8_t MB_getEndian(void);

    void MB_setCalWgt(const uint8_t *reg);
    void MB_getCalWgt(uint8_t *reg);


    //discrete_reg

    uint8_t MB_getStabFlag(void);
    uint8_t MB_getZeroFlag(void);
    uint8_t MB_getTareFlag(void);
    uint8_t MB_getOverLoadFlag(void);
    uint8_t MB_getLoFlag(void);
    uint8_t MB_getOkFlag(void);
    uint8_t MB_getHiFlag(void);

    uint8_t MB_getCalSuccess();

    void MB_setZeroFlag(uint8_t reg);
    void MB_setTareFlag(uint8_t reg);

    void float_to_buf(float a,uint8_t *buf);
    void long_to_buf(long a,uint8_t *buf);
    void short_to_buf(short a,uint8_t *buf);

    short buf_to_short(const uint8_t *buf);
    long buf_to_long(const uint8_t *buf);
    float buf_to_float(const uint8_t *buf);

signals:
    void sTare(bool);
    void sPretare(float tare);
    void sSetHi(float hi);
    void sSetLow(float low);
    void sSetDevAddr(uint8_t addr);
    void sZero(void);
    void sSetAdw(float adw);

private slots:
    void setAdw(float adw);
    void setHi(float hi);
    void setLow(float low);
    void setDevAddr(uint8_t dev);

private:
    static const uint32_t expTab[];
    MBRegHandler(MainWidget *);
    static const INPUT_REG mb_tab_input_reg[];
    static const HOLDING_REG mb_tab_holding_reg[];
    static const SINGLE_COIL mb_tab_coil_reg[];
    static const DISCRETE_INPUT mb_tab_discrete_reg[];

    static MBRegHandler *mHandler;
//    float mNet;
//    float mGross;
//    float mTare;
    float mHi;
    float mLow;
    //Scale *mScale;
    SpScaleAdaptor* mScaleAdaptor;
    uint8_t mDevAddr;
    EndianMode mEndian;
    ChkRslt mChkRslt;
    bool mCalSuccess;
};



#endif // MBREGHANDLER_H
